package com.qf.service.impl;

import com.qf.dao.repository.UserCodeRepository;
import com.qf.dao.repository.UserRepository;
import com.qf.pojo.dto.LiveUser;
import com.qf.pojo.dto.UserCode;
import com.qf.pojo.reqVo.LiveUserReq;
import com.qf.pojo.resVo.BaseResult;
import com.qf.service.UserService;
import com.qf.utils.EmailUtils;
import com.qf.utils.JWTUtils;
import com.qf.utils.MD5Util;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    UserRepository userRepository;

    @Autowired
    EmailUtils emailUtils;

    @Autowired
    UserCodeRepository userCodeRepository;

    @Autowired
    JWTUtils jwtUtils;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    RabbitTemplate rabbitTemplate;

    @Override
    public BaseResult validataEmail(String email) {
       LiveUser liveUser = userRepository.findByEmail(email);
       if (liveUser!=null){
           //代表当前邮箱已经被注册过了
           return new BaseResult().fail();
       }
        return new BaseResult().success();
    }

    @Override
    public BaseResult validataloginName(LiveUserReq liveUserReq) {

     LiveUser liveUser =  userRepository.findByLoginName(liveUserReq.getLoginName());
        if (liveUser!=null){
            //代表当前邮箱已经被注册过了
            return new BaseResult().fail();
        }
        return new BaseResult().success();
    }

    @Override
    public BaseResult getCode(String email) {
        //给email发送邮件
//        String code = emailUtils.sendMail(email);
//        if (!StringUtils.isEmpty(code)){
//            //将验证码存储在要给地方，以往存储在session中，但是现在舍弃掉session，所以存储在数据库
//            UserCode userCode = new UserCode();
//            userCode.setUserEmail(email);
//            userCode.setCode(code);
//            userCode.setCreateTime(new Date());
//            //判断 如果该用户已经发送过验证码，则需要修改验证码不能重新添加一条数据，用户名应该保持唯一
//            UserCode byUserEmail = userCodeRepository.findByUserEmail(email);
//            UserCode save=null;
//            if (byUserEmail==null){
//                save = userCodeRepository.save(userCode);
//            }else{
//                byUserEmail.setCode(code);
//                save= userCodeRepository.saveAndFlush(byUserEmail);
//            }
//
//
//            if (save!=null){
//                return new BaseResult().success();
//            }
//        }
//        return new BaseResult().fail();
        //逻辑改造，使用rabbitmq进行邮件的发送
        CorrelationData correlationData = new CorrelationData();
        //设置消息的id值
        correlationData.setId(UUID.randomUUID().toString());
        rabbitTemplate.convertAndSend("qf-live-email","",email,correlationData);

        return new BaseResult().success();
    }

    @Override
    public BaseResult registry(LiveUserReq liveUserReq) {
        LiveUser liveUser = userRepository.findByEmail(liveUserReq.getEmail());
        if (liveUser!=null){
            //代表当前邮箱已经被注册过了
            return new BaseResult().fail();
        }
        LiveUser loginLiveUser =  userRepository.findByLoginName(liveUserReq.getLoginName());
        if (loginLiveUser!=null){
            //代表当前用户名已经被注册过了
            return new BaseResult().fail();
        }
        //判断验证码是否一致
       //UserCode userCode = userCodeRepository.findByUserEmail(liveUserReq.getEmail());
        Boolean aBoolean = redisTemplate.hasKey(liveUserReq.getEmail());
        if (!aBoolean){
            return new BaseResult(0,"验证码不存在！请先发送验证码！",null,null);
        }
        Object o = redisTemplate.opsForValue().get(liveUserReq.getEmail());
        if (!o.toString().equals(liveUserReq.getCode())){
            return new BaseResult(0,"验证码错误!",null,null);
        }
        //经过以上判断，通过了验证规则，就可以进行用户的注册！，注意注册时，需要将密码经过MD5的加密
        String stringMD5 = MD5Util.getStringMD5(liveUserReq.getPassword());
        liveUserReq.setPassword(stringMD5);
        //进行Bean对象的copy;
        LiveUser liveUser1 = new LiveUser();
        //将bean对象中的属性进行复制
        BeanUtils.copyProperties(liveUserReq,liveUser1);
        liveUser1.setCreateTime(new Date());
        liveUser1.setStatus(1);
        //存储
        LiveUser save = userRepository.save(liveUser1);
        if (save!=null){
            return new BaseResult().success();
        }
        return new BaseResult().fail();
    }

    @Override
    public BaseResult login(LiveUserReq liveUserReq) {
        //非空判断
        if (StringUtils.isEmpty(liveUserReq.getLoginName())){
            return new BaseResult().fail();
        }
        if (StringUtils.isEmpty(liveUserReq.getPassword())){
            return new BaseResult().fail();
        }
        //进行登录的验证 ，通过用户名获取用户对象
        LiveUser byLoginName = userRepository.findByLoginName(liveUserReq.getLoginName());
        if (byLoginName==null){
            return new BaseResult(0,"用户未注册!请先注册！",null,null);
        }
        //进行密码的比对
        String passworMD5 = MD5Util.getStringMD5(liveUserReq.getPassword());
        if (!byLoginName.getPassword().equals(passworMD5)){
            return new BaseResult(0,"密码错误！",null,null);
        }
        //生成token串，将token存储到redis中
        String token = jwtUtils.createToken(byLoginName);
        //生成一个uuid ，以uuid为key，将token设置在redis中
        String key = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(key,token);
        //设置当前用户的token的有效时长！代表token的存活时间为60分钟，如果60分钟用户没有任何操作，则用户需重新登录
        redisTemplate.expire(key,60, TimeUnit.MINUTES);
        return new BaseResult(1,"登录成功！",key,null);
    }

    @Override
    public BaseResult findUserByToken(HttpServletRequest request) {
        //获取到token
        String token = request.getHeader("token");
        if (StringUtils.isEmpty(token)){
            return new BaseResult(0,"用户未登录！",null,null);
        }
        //在Redis中进行验证,因为在存储token时，设置了1个小时的存活时长，保证用户的安全性，所以有可能在Redis中是没有该key值存在的
        Boolean aBoolean = redisTemplate.hasKey(token);
        if (!aBoolean){
            return new BaseResult(0,"登录信息以失效！",null,null);
        }
        //延长用户的token/登陆状态存活时长
        redisTemplate.expire(token,60,TimeUnit.MINUTES);
        Object jwtToken = redisTemplate.opsForValue().get(token);
        //使用jwtutils解析token，获取到当前的登录名
        String userName = jwtUtils.verfiyToken(jwtToken.toString());
        if (StringUtils.isEmpty(userName)){
            return new BaseResult(0,"token信息以过期！",null,null);
        }
        //通过用户名查询用户的数据
        LiveUser byLoginName = userRepository.findByLoginName(userName);
        return new BaseResult(1,"获取成功！",byLoginName,null);
    }
}
